package com.istock.union.filter;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.http.HttpStatus;
import org.springframework.web.method.HandlerMethod;

import com.istock.base.serializer.JsonSerializer;
import com.istock.base.serializer.json.JsonSerializerFactory;
import com.istock.union.user.client.SSOClientUtils;
import com.istock.union.user.filter.AuthorizationCallbackAdapter;
import com.istock.union.user.model.SecurityChecker;
import com.istock.union.user.model.SecurityExpression;
import com.istock.union.user.utils.WebCommonUtils;

public class SecurityCheckCallback extends AuthorizationCallbackAdapter{

	private Logger logger = LoggerFactory.getLogger(getClass());

	private String forbiddenUrl = "";
	
	@Override
	public boolean preCallback(HttpServletRequest request, HttpServletResponse response, HandlerMethod targetObj) {
		
		boolean hasPermission = false;//默认没有权限
		
		SecurityChecker checkerAnnotation = targetObj.getMethodAnnotation(SecurityChecker.class);
		SecurityExpression expressionAnnotation = targetObj.getMethodAnnotation(SecurityExpression.class);
		if(checkerAnnotation == null && expressionAnnotation == null) {
			//如果2个都没有配置
			hasPermission = true;
		}else {
			//如果有配置其中一个annotation
			if(checkerAnnotation != null) {
				hasPermission = SSOClientUtils.getInstance().hasPermiss(checkerAnnotation.value());
			}
			if(expressionAnnotation != null) {
				hasPermission = checkExpression(expressionAnnotation.value());
			}
		}
		
		if(hasPermission) {
			return true;
		}else {
			//没有权限
			logger.info("the permissStr:{} , current can't has the permiss" , checkerAnnotation.value());
			try {
				writeResponse(request , response);
			} catch (Exception e) {
				logger.error("permission return page exception " , e);
			}
			return false;
		}
	}
	
	private static ExpressionParser parser = new SpelExpressionParser();
	private boolean checkExpression(String expression) {
		StandardEvaluationContext contenxt = new StandardEvaluationContext();
		try {
			Method method = getClass().getDeclaredMethod("hasPermission", new Class[] {String.class});
			contenxt.registerFunction("hasPermission", method);
			return parser.parseExpression(expression).getValue(contenxt , Boolean.class);
		}catch(Exception e) {
			logger.error("check expression exception" , e);
		}
		return false;
	}
	
	public static boolean hasPermission(String str) {
		return SSOClientUtils.getInstance().hasPermiss(str);
	}
	
	public void writeResponse(HttpServletRequest request , HttpServletResponse response) throws Exception {
		boolean isAjax = WebCommonUtils.isAjax(request);
		if(isAjax){
			//如果是ajax,返回403,由前端负责跳转到登录页面
			response.setStatus(HttpStatus.FORBIDDEN.value());
			Map<String , Object> resultMap = new HashMap<String, Object>();
			resultMap.put("forbiddenUrl", WebCommonUtils.generateTargetUrl(request.getContextPath(), forbiddenUrl));
			
			response.setContentType("application/json");
			JsonSerializer serializer = JsonSerializerFactory.findSerializer();
			response.getWriter().println(serializer.serialize(resultMap));
			response.getWriter().flush();
			return;
		}
		
		response.sendRedirect(WebCommonUtils.generateTargetUrl(request.getContextPath(), forbiddenUrl));
	}
}
